package parser;

import java.io.PrintWriter;
import java.util.ArrayList;
import lexer.TokenType;

/**
 * The main node in the AST for a LOGO Program. Mainly just reads in Procedures.
 * Also handles some error handling logic
 */
public class LogoProgram extends LogoGrammar {

	ArrayList<LogoProcedure> procedures;

	public LogoProgram(TokenIterator it, LogoScope scope) throws LogoParseException {
		procedures = new ArrayList<LogoProcedure>();
		parseProceduresFromTokens(it, scope);
	}

	/**
	 * Returns true if the program contains a function called "MAIN"
	 */
	public boolean containsMainFunction() {
		for (LogoProcedure proc : procedures) {
			if (proc.identifier.equals("MAIN")) {
				return true;
			}
		}
		return false;
	}

	private void parseProceduresFromTokens(TokenIterator it, LogoScope scope) throws LogoParseException {
		LogoParseException exception = null;

		while (it.hasNext()) {
			if (it.peek().getType() == TokenType.BEGIN_PROC) {
				try {
					procedures.add(new LogoProcedure(it, scope));
				} catch (LogoParseException e) {
					System.out.println(e.getMessage() + "\n");
					exception = e;
				}
			} else {
				it.next();
			}
		}
		if (exception != null) {
			throw new LogoParseException("\nErrors encountered during compilation. See above for more details");
		}
	}

	@Override
	public void resolveIdentifiers(LogoScope scope) throws LogoParseException {
		for (LogoProcedure proc : procedures) {
			proc.resolveIdentifiers(scope);
		}
	}

	/**
	 * Example Output: Just a whole LOGO program in PostScript form
	 */
	@Override
	public void generatePostScriptCode(PrintWriter stream) {
		for (LogoProcedure proc : procedures) {
			proc.generatePostScriptCode(stream);
		}
	}
}
